package org.orarriinae.common.web.assertion;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.orarriinae.common.base.exception.ErrorInfo;
import org.orarriinae.common.base.exception.ServiceException;
import org.orarriinae.common.web.error.DataException;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;

/**
 * 业务断言，对对象或字段的值进行判断，如果不满足条件，抛出异常{@link ServiceException}
 *
 * @author Wang Chengwei
 * @author xie jin
 * @since 1.0
 */
@Slf4j
public final class ServiceAssert {

    private ServiceAssert() {
    }

    /**
     * 判断对象是否为空
     *
     * @param message 错误信息
     */
    public static void notNull(Object obj, String message) {
        if (obj == null) {
            throw new DataException(message);
        }
    }

    /**
     * 判断对象是否为空
     *
     * @param errorInfo 错误信息
     */
    public static void notNull(Object obj, ErrorInfo errorInfo) {
        if (obj == null) {
            throw new DataException(errorInfo);
        }
    }

    /**
     * 判断对象是否为空
     *
     * @param clz     要抛出的异常类
     * @param message 错误信息
     */
    public static void notNull(Object obj, Class<? extends ServiceException> clz, String message) {
        if (obj == null) {
            throwException(clz, message);
        }
    }

    /**
     * 判断对象是否为空
     *
     * @param clz       要抛出的异常类
     * @param errorInfo 错误信息
     */
    public static void notNull(Object obj, Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        if (obj == null) {
            throwException(clz, errorInfo);
        }
    }

    /**
     * 判断字符串是否为空
     *
     * @param message 错误信息
     */
    public static void notEmpty(String obj, String message) {
        if (StringUtils.isEmpty(obj)) {
            throw new DataException(message);
        }
    }

    /**
     * 判断字符串是否为空
     *
     * @param errorInfo 错误信息
     */
    public static void notEmpty(String obj, ErrorInfo errorInfo) {
        if (StringUtils.isEmpty(obj)) {
            throw new DataException(errorInfo);
        }
    }

    /**
     * 判断字符串是否为空
     *
     * @param clz     要抛出的异常类
     * @param message 错误信息
     */
    public static void notEmpty(String obj, Class<? extends ServiceException> clz, String message) {
        if (StringUtils.isEmpty(obj)) {
            throwException(clz, message);
        }
    }


    /**
     * 判断字符串是否为空
     *
     * @param clz       要抛出的异常类
     * @param errorInfo 错误信息
     */
    public static void notEmpty(String obj, Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        if (StringUtils.isEmpty(obj)) {
            throwException(clz, errorInfo);
        }
    }
    /**
     * 判断字符串是否为空
     *
     * @param clz       要抛出的异常类
     * @param errorInfo 错误信息
     */
    public static void notEmpty(Object obj, Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        if (Objects.isNull(obj)) {
            throwException(clz, errorInfo);
        }
    }
    /**
     * 判断Map是否为空
     *
     * @param message 错误信息
     */
    public static void notEmpty(Map<?, ?> map, String message) {
        if (map == null || map.isEmpty()) {
            throw new DataException(message);
        }
    }

    /**
     * 判断Map是否为空
     *
     * @param errorInfo 错误信息
     */
    public static void notEmpty(Map<?, ?> map, ErrorInfo errorInfo) {
        if (map == null || map.isEmpty()) {
            throw new DataException(errorInfo);
        }
    }

    /**
     * 判断Map是否为空
     *
     * @param clz     要抛出的异常类
     * @param message 错误信息
     */
    public static void notEmpty(Map<?, ?> map, Class<? extends ServiceException> clz, String message) {
        if (map == null || map.isEmpty()) {
            throwException(clz, message);
        }
    }

    /**
     * 判断Map是否为空
     *
     * @param clz       要抛出的异常类
     * @param errorInfo 错误信息
     */
    public static void notEmpty(Map<?, ?> map, Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        if (map == null || map.isEmpty()) {
            throwException(clz, errorInfo);
        }
    }

    /**
     * 判断集合是否为空
     *
     * @param message 错误信息
     */
    public static void notEmpty(Collection<?> collection, String message) {
        if (collection == null || collection.isEmpty()) {
            throw new DataException(message);
        }
    }

    /**
     * 判断集合是否为空
     *
     * @param errorInfo 错误信息
     */
    public static void notEmpty(Collection<?> collection, ErrorInfo errorInfo) {
        if (collection == null || collection.isEmpty()) {
            throw new DataException(errorInfo);
        }
    }


    /**
     * 判断集合是否为空
     *
     * @param clz     要抛出的异常类
     * @param message 错误信息
     */
    public static void notEmpty(Collection<?> collection, Class<? extends ServiceException> clz, String message) {
        if (collection == null || collection.isEmpty()) {
            throwException(clz, message);
        }
    }


    /**
     * 判断集合是否为空
     *
     * @param clz       要抛出的异常类
     * @param errorInfo 错误信息
     */
    public static void notEmpty(Collection<?> collection, Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        if (collection == null || collection.isEmpty()) {
            throwException(clz, errorInfo);
        }
    }

    /**
     * 校验是否更新
     *
     * @param rows 更新的行数
     * @param ex   要抛出的异常
     */
    public static void checkUpdate(int rows, ServiceException ex) {
        if (rows == 0) {
            throw ex;
        }
    }

    /**
     * 校验是否有关联关系
     *
     * @param rows 更新的行数
     * @param ex   要抛出的异常
     */
    public static void checkRef(int rows, ServiceException ex) {
        if (rows == 0) {
            throw ex;
        }
    }

    /**
     * 校验是否更新
     *
     * @param rows    更新的行数
     * @param clz     要抛出的异常
     * @param message 错误信息
     */
    public static void checkUpdate(int rows, Class<? extends ServiceException> clz, String message) {
        if (rows == 0) {
            throwException(clz, message);
        }
    }

    /**
     * 校验是否有关联关系
     *
     * @param rows    更新的行数
     * @param clz     要抛出的异常
     * @param message 错误信息
     */
    public static void checkRef(int rows, Class<? extends ServiceException> clz, String message) {
        if (rows == 0) {
            throwException(clz, message);
        }
    }


    /**
     * 校验是否更新
     *
     * @param rows      更新的行数
     * @param clz       要抛出的异常
     * @param errorInfo 错误信息
     */
    public static void checkUpdate(int rows, Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        if (rows == 0) {
            throwException(clz, errorInfo);
        }
    }

    /**
     * 校验是否有关联关系
     *
     * @param rows      更新的行数
     * @param clz       要抛出的异常
     * @param errorInfo 错误信息
     */
    public static void checkRef(int rows, Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        if (rows == 0) {
            throwException(clz, errorInfo);
        }
    }

    public static void throwException(Class<? extends ServiceException> clz, String message) {
        try {
            Constructor<? extends ServiceException> constructor = clz.getConstructor(String.class);
            throw constructor.newInstance(message);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            log.warn(e.getMessage(), e);
            throw new DataException(message);
        }
    }

    public static void throwException(Class<? extends ServiceException> clz, ErrorInfo errorInfo) {
        try {
            Constructor<? extends ServiceException> constructor = clz.getConstructor(ErrorInfo.class);
            throw constructor.newInstance(errorInfo);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            log.warn(e.getMessage(), e);
            throw new DataException(errorInfo);
        }
    }

}
